module demo (
    input           clk,
    input           rst_n,
    input   [3:0]   i_data,
    input   [3:0]   q_data,
    input           ready_in,
    input   [1:0]   sel,
    output  [4:0]   out_data,
    output          ready_out     
);

    reg [3:0] i_data_reg;
    reg [3:0] q_data_reg;
    reg [3:0] out_data_reg;

    reg [3:0] cnt;

    //计数器
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            cnt<=4'b0;                     //复位为0时,计数器置零
        
        else if(cnt==4'd8)
            cnt<=4'b0;                     //当计数器达到最大值4'd8时,计数器清零
        
        else 
            cnt<=cnt+1'b1;                 //正常情况下,每一次时钟上升沿或复位信号下降沿,计数器自加一
    end

    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)                         //复位为0时,寄存器置零
            i_data_reg<=4'd0;   
        else if(cnt==4'd4)                 //当计数器到4'd4时,寄存器置4'd3
            i_data_reg<=4'd3;
        else if(ready_in)                  //ready_in有效时,把i_data赋给i_data_reg
            i_data_reg<=i_data;
    end

    //同上
    always @(posedge clk or negedge rst_n) begin
        if(!rst_n)
            q_data_reg<=4'd0;
        else if(cnt==4'd4)
            q_data_reg<=4'd3;
        else if(ready_in)
            q_data_reg<=q_data;
    end  

//-------------------------------------写法1------------------------------------------//
//用case语句,通过sel的值,进行选择
/*
    //MUX
    always @(*) begin
        case (sel)
            2'b00:  out_data_reg = i_data_reg;
            2'b01:  out_data_reg = i_data_reg * q_data_reg;
            2'b10:  out_data_reg = i_data_reg & q_data_reg;
            2'b11:  out_data_reg = i_data_reg && q_data_reg;
            default:;
        endcase
    end

    assign out_data = out_data_reg;
    assign ready_out = ready_in;
*/

//-------------------------------------写法2------------------------------------------//
//三目运算符,与写法1结果相同
    //MUX
    assign out_data = (sel==2'b00) ?  i_data_reg : 
                      (sel==2'b01) ? (i_data_reg * q_data_reg) :
                      (sel==2'b10) ? (i_data_reg & q_data_reg) :
                                     (i_data_reg && q_data_reg);
    assign ready_out = ready_in;

endmodule